﻿#ifndef DOCUMENTTABWIDGET_H
#define DOCUMENTTABWIDGET_H

#include <QTabWidget>
#include <QMenu>
#include <QMouseEvent>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QTabBar>
#include <QDebug>

class DocumentTabWidget : public QTabWidget
{
	Q_OBJECT
public:
	explicit DocumentTabWidget(QWidget* parent = nullptr)
		: QTabWidget(parent)
	{
		setMovable(true);
		setContextMenuPolicy(Qt::CustomContextMenu);
		connect(this, &QTabWidget::customContextMenuRequested,
			this, &DocumentTabWidget::showTabContextMenu);

		setAcceptDrops(true);

		connect(this, &QTabWidget::currentChanged,
			this, &DocumentTabWidget::onCurrentChanged);
	}

	int DocumentTabWidget::addDocumentTab(const QString& title, const QString& key, bool isModified)
	{
		if (!this || thread() == nullptr)
		{
			qCritical() << "致命错误：调用已销毁的DocumentTabWidget！";
			return -1;
		}

		if (parent() && (parent()->thread() == nullptr)) 
		{
			qCritical() << "父对象已销毁，无法添加标签！";
			return -1;
		}

		QWidget* tabWidget = new QWidget(this); 
		if (!this || thread() == nullptr) 
		{
			qCritical() << "当前标签栏已销毁，addTab失败！";
			delete tabWidget; // 避免内存泄漏
			return -1;
		}

		int index = addTab(tabWidget, title);
		if (index < 0 || index >= count())
		{
			qWarning() << "addTab返回无效索引：" << index;
			m_tabKeys.append(key); 
		}
		else 
		{
			m_tabKeys.insert(index, key);
		}

		updateTabModifiedState(index, isModified);
		return index;
	}

	void updateTabModifiedState(int index, bool modified)
	{
		if (index < 0 || index >= count()) return;
		QString title = tabText(index);
		QString cleanTitle = title.endsWith("*") ? title.left(title.length() - 1) : title;
		setTabText(index, modified ? cleanTitle + "*" : cleanTitle);
	}

	QString getTabKey(int index) const
	{
		return (index >= 0 && index < m_tabKeys.size()) ? m_tabKeys[index] : "";
	}

	void removeTabWithKey(int index)
	{
		if (index >= 0 && index < m_tabKeys.size()) 
			m_tabKeys.removeAt(index); 
		removeTab(index);
	}

	void clear()
	{
		disconnect(this, &QTabWidget::currentChanged, this, &DocumentTabWidget::onCurrentChanged);
		disconnect(this, &QTabWidget::customContextMenuRequested, this, &DocumentTabWidget::showTabContextMenu);

		m_tabKeys.clear();
		
		while (count() > 0) 
		{
			if (widget(0)) 
			{ 
				QTabWidget::removeTab(0); 
			}
			else 
			{
				qWarning() << "跳过无效标签（部件已销毁）";
				break; 
			}
		}

		connect(this, &QTabWidget::currentChanged, this, &DocumentTabWidget::onCurrentChanged);
		connect(this, &QTabWidget::customContextMenuRequested, this, &DocumentTabWidget::showTabContextMenu);
	}

	void removeTab(int index)
	{
		if (index >= 0 && index < m_tabKeys.size())
		{
			m_tabKeys.removeAt(index); 
		}
		QTabWidget::removeTab(index);
	}

protected:
	void showTabContextMenu(const QPoint& pos)
	{
		QMenu menu(this);
		QAction* closeCurrentAction = menu.addAction("关闭当前标签");
		QAction* closeOtherAction = menu.addAction("关闭其他标签");

		QAction* selectedAction = menu.exec(mapToGlobal(pos));
		QTabBar* tabBar = this->tabBar();
		if (!tabBar) return;

		int currentIndex = tabBar->tabAt(pos);
		if (currentIndex == -1) return;

		if (selectedAction == closeCurrentAction)
		{
			QString key = getTabKey(currentIndex);
			emit closeTabRequested(currentIndex, key);
		}
		else if (selectedAction == closeOtherAction)
		{
			for (int i = count() - 1; i >= 0; --i)
			{
				if (i != currentIndex)
				{
					QString key = getTabKey(i);
					emit closeTabRequested(i, key);
				}
			}
		}
	}

	void dragEnterEvent(QDragEnterEvent* event) override
	{
		if (event && event->mimeData() &&
			event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) {
			event->acceptProposedAction();
		}
	}

	void dropEvent(QDropEvent* event) override
	{
		QTabWidget::dropEvent(event);
	}

private slots:
	
	void onCurrentChanged(int index)
	{
		emit tabSwitched(index);
	}

	void onTabCloseClicked(int index)
	{
		if (index < 0 || index >= count()) return;
		emit checkTabSaveState(index, m_tabKeys[index]);
	}

signals:
	void tabCloseConfirmed(int index, const QString& key);
	void closeTabRequested(int index, const QString& key);
	void tabSwitched(int index);
	void checkTabSaveState(int index, const QString& key);

private:
	QList<QString> m_tabKeys;
};

#endif // DOCUMENTTABWIDGET_H
